package com.example.musicplayer.gobang;

public class Gobang {
    public static final int EMPTY = 0;
    //black chessman
    public static final int BLACK = 1;
    //white chessman
    public static final int WHITE = 2;
    //the size of chessboard
    private static final int SIZE = 15;
    //record the chessman info
    private final int[][] mChess;
    //record the chessman order
    private final int[][] mRecord;
    //record the num of chessman
    private int mCounts;
    //current round if black or white
    private int mRound;

    public Gobang() {
        mChess = new int[SIZE][SIZE];
        mRecord = new int[2][SIZE * SIZE];
        newGame();
    }

    public void newGame() {
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                mChess[i][j] = EMPTY;
            }
        }
        mCounts = 0;
        mRound = BLACK;
    }

    //add a chess in chessboard
    public boolean addChess(int x, int y) {
        if (x < 0 || x >= SIZE || y < 0 || y >= SIZE || mChess[x][y] != EMPTY) {
            return false;
        }
        mChess[x][y] = mRound;
        mRecord[0][mCounts] = x;
        mRecord[1][mCounts] = y;
        mCounts++;
        mRound = getOppositeRound();
        return true;
    }

    public Location backChess() {
        if (mCounts > 0) {
            int x = mRecord[0][mCounts - 1];
            int y = mRecord[1][mCounts - 1];
            mChess[x][y] = EMPTY;
            mCounts--;
            mRound = getOppositeRound();
            return new Location(x, y);
        }
        return null;
    }

    public boolean win() {
        return isWin(mChess, mRecord[0][mCounts - 1], mRecord[1][mCounts - 1], getOppositeRound());
    }

    public int getCounts() {
        return mCounts;
    }

    public int getRound() {
        return mRound;
    }

    public int getOppositeRound() {
        if (mRound == BLACK) {
            return WHITE;
        } else {
            return BLACK;
        }
    }

    public int getChess(int x, int y) {
        return mChess[x][y];
    }

    public int getLocX(int stepPosition) {
        if (stepPosition >= 0 && stepPosition < mCounts) {
            return mRecord[0][stepPosition];
        } else {
            return mRecord[0][mCounts - 1];
        }
    }

    public int getLocY(int stepPosition) {
        if (stepPosition >= 0 && stepPosition < mCounts) {
            return mRecord[1][stepPosition];
        } else {
            return mRecord[1][mCounts - 1];
        }
    }

    public int[][] copyChessLocation() {
        int[][] data = new int[SIZE][SIZE];
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                data[i][j] = mChess[i][j];
            }
        }
        return data;
    }

    public int getChessBoardSize() {
        return SIZE;
    }

    public static int getOppositeRound(int currentRound) {
        if (currentRound == BLACK) {
            return WHITE;
        } else {
            return BLACK;
        }
    }

    /**
     * if win
     *
     * @param data  chess location info
     * @param x     loc x
     * @param y     loc y
     * @param chess chess color
     * @return if add this chess will get five in a row
     */
    public static boolean isWin(int[][] data, int x, int y, int chess) {
        if (data == null) {
            return false;
        }
        int size = data.length;
        if (x < 0 || x >= size) {
            return false;
        }
        if (y < 0 || y >= size) {
            return false;
        }
        //record the num of connected chess
        int counts = 0;
        //horizontal
        for (int i = -4; i <= 4; i++) {
            int temp = y + i;
            if (temp >= 0 && temp < size) {
                if (data[x][temp] == chess) {
                    counts++;
                } else {
                    counts = 0;
                }
                if (counts == 5) {
                    return true;
                }
            }
        }
        //vertical
        counts = 0;
        for (int i = -4; i <= 4; i++) {
            int temp = x + i;
            if (temp >= 0 && temp < size) {
                if (data[temp][y] == chess) {
                    counts++;
                } else {
                    counts = 0;
                }
                if (counts == 5) {
                    return true;
                }
            }
        }
        //direct of forward slash
        counts = 0;
        for (int i = -4; i <= 4; i++) {
            int tempX = x + i;
            int tempY = y - i;
            if (tempX >= 0 && tempX < size && tempY >= 0 && tempY < size) {
                if (data[tempX][tempY] == chess) {
                    counts++;
                } else {
                    counts = 0;
                }
                if (counts == 5) {
                    return true;
                }
            }
        }
        //direct of back slash
        counts = 0;
        for (int i = -4; i <= 4; i++) {
            int tempX = x + i;
            int tempY = y + i;
            if (tempX >= 0 && tempX < size && tempY >= 0 && tempY < size) {
                if (data[tempX][tempY] == chess) {
                    counts++;
                } else {
                    counts = 0;
                }
                if (counts == 5) {
                    return true;
                }
            }
        }
        return false;
    }
}